package com.ph.shopping.facade.score.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ph.shopping.common.core.base.BaseService;
import com.ph.shopping.common.core.customenum.ResultEnum;
import com.ph.shopping.common.core.customenum.TransCodeEnum;
import com.ph.shopping.common.util.com.order.Constants;
import com.ph.shopping.common.util.page.PageBean;
import com.ph.shopping.common.util.result.Result;
import com.ph.shopping.facade.mapper.IScoreMapper;
import com.ph.shopping.facade.score.entity.PhScoreTotalTrade;
import com.ph.shopping.facade.score.request.ScorePageRequest;
import com.ph.shopping.facade.score.service.IScoreService;
import com.ph.shopping.facade.score.vo.MemberCostScore;
import com.ph.shopping.facade.score.vo.MemberScoreShopVo;
import com.ph.shopping.facade.score.vo.MemberScoreVo1;
import com.ph.shopping.facade.score.vo.MemberScoreVo2;

@Component
@Service(version = "1.0.0")
@Transactional(rollbackFor = Exception.class)
public class ScoreServiceImpl extends BaseService implements IScoreService {

	@Autowired
	private IScoreMapper iScoreMapper;

	/**
	 * 积分流水
	 */
	@Override
	public long memberScoreTrade(long memberId, TransCodeEnum codeEnum, long score, String orderNo)
			throws Exception {
		score = codeEnum.getMark() * score;
		switch (codeEnum) {
		case MEMBER_CONSUME:
			return scoreTrade(memberId, codeEnum, score, orderNo);
		case MEMBER_BACK_SCORE:
			return returnMemberScoreTrade(memberId, codeEnum, score, orderNo);
		case MEMBER_DRAWCASH:
			return memberDrawCashTrade(memberId, codeEnum, score, orderNo);
		case MEMBER_DRAWCASHADD:
			return memberDrawCashAddTrade(memberId, codeEnum, score, orderNo);
		case MEMBER_COST_STANDBYSCORE:
			return costMemberStandByScore(memberId, codeEnum, score, orderNo);
		case MEMBER_RETURN_ENABLESCORE:
			return returnMemberEnableScre(memberId, codeEnum, score, orderNo);
		case MEMBER_UNLINE_ORDER:
			return scoreTrade(memberId, codeEnum, score, orderNo);
		default:
			throw new Exception("未知交易码!");
		}
	}

	/**
	 * 
	 * @Title: returnMemberEnableScre
	 * @Description: 增加可用积分
	 * @author WQiang
	 * @date 2017年3月24日 上午9:49:50
	 * @param memberId
	 * @param codeEnum
	 * @param score
	 * @param orderNo
	 * @return
	 * @throws Exception
	 */
	private long returnMemberEnableScre(long memberId, TransCodeEnum codeEnum, long score,
			String orderNo) throws Exception {
		updateMemberScore(memberId, 0, score, 0);

		long setId = getSetId(memberId, score, orderNo, codeEnum.getCode());

		insertIncomeTrade(memberId, score, codeEnum.getCode(), setId, orderNo);

		return setId;
	}

	/**
	 * 
	 * @Title: returnMemberEnableScoreTrade
	 * @Description: 返回可用积分(消耗待用积分，增加可用积分)
	 * @author WQiang
	 * @date 2017年3月23日 下午4:16:35
	 * @param memberId
	 * @param codeEnum
	 * @param standByScore
	 * @param enableScore
	 * @param drawcashScore
	 * @return
	 */
	private long costMemberStandByScore(long memberId, TransCodeEnum codeEnum, long score,
			String orderNo) throws Exception {
		int level = iScoreMapper.getMemberLevel(memberId);
		long enableScore = 0;
		if (level == 1) {// 普通会员
			// 可用积分
			enableScore = (long)((score * Constants.COMM_MEMBER) / Constants.BASE_MEMBER);
			// 剩余待用积分
		} else if (level == 2) {// VIP
			// 可用积分
			enableScore = (long)((score * Constants.VIP_MEMBER) / Constants.BASE_MEMBER);
			// 待用积分
		}

		updateMemberScore(memberId, enableScore, 0, 0);

		long setId = getSetId(memberId, enableScore, orderNo, codeEnum.getCode());

		insertCostTrade(memberId, enableScore, codeEnum.getCode(), setId, orderNo);

		long ret = memberScoreTrade(memberId, TransCodeEnum.MEMBER_RETURN_ENABLESCORE, -enableScore,
				orderNo);
		if (ret < 0) {
			throw new Exception("更新会员可用积分失败!");
		}

		return setId;
	}

	/**
	 * 
	 * @Title: memberDrawCashAddTrade
	 * @Description: 已提现积分累计
	 * @author WQiang
	 * @date 2017年3月22日 下午5:32:01
	 * @param memberId
	 * @param codeEnum
	 * @param standByScore
	 * @param enableScore
	 * @param drawcashScore
	 * @return
	 * @throws Exception
	 */
	private long memberDrawCashAddTrade(long memberId, TransCodeEnum codeEnum, long score,
			String orderNo) throws Exception {
		updateMemberScore(memberId, 0, 0, score);

		long setId = getSetId(memberId, score, orderNo, codeEnum.getCode());

		insertIncomeTrade(memberId, score, codeEnum.getCode(), setId, orderNo);

		return setId;
	}

	/**
	 * 
	 * @Title: memberDrawCashTrade
	 * @Description: 提现消费
	 * @author WQiang
	 * @date 2017年3月22日 下午4:20:45
	 * @param memberId
	 * @param codeEnum
	 * @param score
	 * @return
	 * @throws Exception
	 */
	public long memberDrawCashTrade(long memberId, TransCodeEnum codeEnum, long score,
			String orderNo) throws Exception {
		updateMemberScore(memberId, 0, score, 0);

		long setId = getSetId(memberId, score, orderNo, codeEnum.getCode());

		insertCostTrade(memberId, score, codeEnum.getCode(), setId, orderNo);

		return setId;
	}

	/**
	 * 
	 * @Title: returnMemberScore
	 * @Description: 返回积分(待返积分)
	 * @author WQiang
	 * @date 2017年3月22日 下午4:16:28
	 * @param memberId
	 * @param codeEnum
	 * @param score
	 * @return
	 * @throws Exception
	 */
	public long returnMemberScoreTrade(long memberId, TransCodeEnum codeEnum, long score,
			String orderNo) throws Exception {

		int res = updOnLineOrderIsBackScore(orderNo);
		if (res != 1) {
			if (updUnLineOrderIsBackScore(orderNo) != 1) {
				throw new Exception("更新订单返积分模块失败!");
			}
		}

		updateMemberScore(memberId, score, 0, 0);

		long setId = getSetId(memberId, score, orderNo, codeEnum.getCode());

		insertIncomeTrade(memberId, score, codeEnum.getCode(), setId, orderNo);

		return setId;
	}

	/**
	 * 
	 * @Title: memberScoreTrade
	 * @Description: 用户积分流水
	 * @author WQiang
	 * @date 2017年3月17日 下午4:31:08
	 * @param memberId
	 * @param codeEnum
	 * @param score
	 * @return
	 */
	private long scoreTrade(long memberId, TransCodeEnum codeEnum, long score, String orderNo)
			throws Exception {
		// 更新用户积分
		updateMemberScore(memberId, 0, score, 0);

		long setId = getSetId(memberId, score, orderNo, codeEnum.getCode());
		logger.debug("-------------------------------------->" + setId);
		// insertIncomeTrade(memberId, score, codeEnum.getCode(), setId);
		insertCostTrade(memberId, score, codeEnum.getCode(), setId, orderNo);

		return setId;
	}

	/**
	 * 
	 * @Title: getSetId
	 * @Description: 获取setId
	 * @author WQiang
	 * @date 2017年3月22日 下午5:24:01
	 * @param memberId
	 * @param standByScore
	 * @param enableScore
	 * @param drawcashScore
	 * @return
	 * @throws Exception
	 */
	private long getSetId(long memberId, long score, String orderNo, int transCode)
			throws Exception {
		PhScoreTotalTrade totalTrade = new PhScoreTotalTrade();
		totalTrade.setMemberId(memberId);
		totalTrade.setScore(score);
		totalTrade.setOrderNo(orderNo);
		totalTrade.setTransCode(transCode);

		insertMemberTrade(totalTrade);

		return totalTrade.getId();
	}

	/**
	 * 更新用户积分
	 */
	private void updateMemberScore(long memberId, long standByScore, long enableScore,
			long drawcashScore) throws Exception {
		if (iScoreMapper.updateMemberScore(memberId, standByScore, enableScore, drawcashScore) != 1) {
			throw new Exception("更新用户积分失败!");
		}
	}

	/**
	 * 记入总流水
	 */
	private int insertMemberTrade(PhScoreTotalTrade totalTrade) throws Exception {
		int ret = iScoreMapper.insertMemberTrade(totalTrade);
		if (ret != 1l) {
			throw new Exception("记入总流水失败!");
		}

		return ret;
	}

	/**
	 * 记入收入流水
	 */
	private void insertIncomeTrade(long memberId, long score, int transCode, long setId,
			String orderNo) throws Exception {
		if (iScoreMapper.insertIncomeTrade(memberId, transCode, score, setId, orderNo) != 1) {
			throw new Exception("记入收入流水失败!");
		}

	}

	/**
	 * 记入支出流水
	 */
	private void insertCostTrade(long memberId, long score, int transCode, long setId,
			String orderNo) throws Exception {
		if (iScoreMapper.insertCostTrade(memberId, transCode, score, setId, orderNo) != 1) {
			throw new Exception("记入支出流水失败!");
		}
	}

	// 统计会员线上订单金额
	public long getOnLineOrderMoney(long memberId) {
		return iScoreMapper.countOnLineMoney(memberId);
	}

	// 统计会员线下订单金额
	public long getUnLineOrderMoney(long memberId) {
		return iScoreMapper.countUnLineMoney(memberId);
	}

	/**
	 * Title: getMemberScore Description: 获取用户积分
	 * 
	 * @author WQiang
	 * @date 2017年3月22日 下午5:45:50
	 * @param memberId
	 * @return
	 * @throws Exception
	 * @see com.ph.shopping.facade.score.service.IScoreService#getMemberScore(long)
	 */
	@Override
	public MemberScoreVo2 getMemberScore(long memberId) {

		return iScoreMapper.getScore(memberId);
	}

	@Override
	public List<MemberScoreVo1> getMemberScores() {
		return iScoreMapper.getMemberScores();
	}

	/**
	 * 商城个人积分流水分页查询
	 * 
	 * @param page
	 * @param scorePageRequest
	 * @return Result
	 */
	@Override
	public Result getMemberScorePage(PageBean page, ScorePageRequest scorePageRequest) {
		try {
			logger.info("商城个人积分流水分页查询入参，page={}，scorePageRequest={}", JSON.toJSONString(page),
					JSON.toJSONString(scorePageRequest));
			PageHelper.startPage(page.getPageNum(), page.getPageSize());
			List<MemberScoreShopVo> list = iScoreMapper.getMemberScorePage(scorePageRequest
					.getMemberId());
			PageInfo<MemberScoreShopVo> pageInfo = new PageInfo<>(list);
			return getResult(ResultEnum.SUCCESS, pageInfo.getList(), pageInfo.getTotal());
		} catch (Exception e) {
			logger.error("商城个人积分流水分页查询异常，e={}", e);
		}
		return null;
	}

	@Override
	public List<MemberCostScore> getMemberCostScore() {
		return iScoreMapper.getMemberCostScore();
	}

	// 更新线上订单状态
	public int updOnLineOrderIsBackScore(String orderNo) throws Exception {
		int res = iScoreMapper.updateOrderIsBackScore1(orderNo);

		return res;
	}

	// 更新线上订单状态
	public int updUnLineOrderIsBackScore(String orderNo) throws Exception {
		int res = iScoreMapper.updateOrderIsBackScore2(orderNo);
		return res;
	}
}
